package com.alks.common.config.interceptor;

import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.JWTUtil;
import com.alks.entity.data.enums.RedisAutoEnum;
import com.alks.common.data.enums.system.LoginPermEnum;
import com.alks.entity.exception.TokenErrorException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Slf4j
public class AuthenticateInterceptor implements HandlerInterceptor {
    @Autowired
    RedisService redisService;

    /*在执行Controller的任务之前判断是否有Session信息
      如果有Session信息就往下执行，去调用Controller。
      如果没有Session就跳转到登录页面
    */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        String token = request.getHeader("Authorization");
//        判空
        if (StringUtils.isEmpty(token)){
            if (request.getRequestURI().endsWith("/sys/file/export/record/rt")) {
                token = request.getParameter("token");
            }
            if (StringUtils.isEmpty(token)) {
                log.warn("未携带token");
                throw new TokenErrorException("未携带token");
            }
        }

        /*登录白名单*/
        if (LoginPermEnum.tokenExist(token)){
            SysUserTokenDTO userTokenDTO = LoginPermEnum.getUserByToken(token);
            UserIdThread.set(userTokenDTO);
            return true;
        }

        String tokenKey = redisService.get(token);
        if (tokenKey==null){
            log.warn("token已过期");
            throw new TokenErrorException("token已过期");
        }
        SysUserTokenDTO userTokenDTO = JWTUtil.parseToken(tokenKey);
        String baseToken = userTokenDTO.getUserId()+"_token";
        UserIdThread.set(userTokenDTO);

        //1.判断请求是否有效
        if (redisService.get(baseToken) == null
                || !redisService.get(baseToken).equals(tokenKey)) {
            return false;
        }
        RedisAutoEnum[] values = RedisAutoEnum.values();
        for (RedisAutoEnum value : values) {
            if (value.getKey().equals(baseToken))
                return true;
        }
        //2.判断是否需要续期
        if (redisService.getExpireTime(baseToken) < 60 * 3000) {
            redisService.setOutTime(baseToken,  60 * 60 * 8 * 1000, TimeUnit.MILLISECONDS);
            log.debug("update token info, id is:{}, user info is:{}", baseToken, token);
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}